/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - core/math
// Copyright (c) 2014.  All Rights Reserved
//
// File:		AEMatrix4f.h
// Author:		Gianluca Belardelli
// Date:		27/07/2013
//
// Revision:	06/02/2014 - Cambiata l'interfaccia e il nome della 
//				classe per supportare i vettori AEVector4f.
/////////////////////////////////////////////////////////////////////////
#ifndef _AEMATRIX4F_INL_
#define _AEMATRIX4F_INL_

AE_FORCEINLINE const AEMatrix4f& AE_CALL AEMatrix4f::GetIdentity( void )
{
	return reinterpret_cast<const AEMatrix4f&>( g_vectorfConstants[AE_QUADREAL_1000] );
}

AE_FORCEINLINE AEMatrix4f::AEMatrix4f( float c0r0, float c1r0, float c2r0, float c3r0,
                        	float c0r1, float c1r1, float c2r1, float c3r1,
                        	float c0r2, float c1r2, float c2r2, float c3r2,
                        	float c0r3, float c1r3, float c2r3, float c3r3,
                        	AEMatrixLayout aemlLayout )
{
	Set( c0r0, c1r0, c2r0, c3r0,
		c0r1, c1r1, c2r1, c3r1,
		c0r2, c1r2, c2r2, c3r2,
		c0r3, c1r3, c2r3, c3r3,
		aemlLayout );
}

AE_FORCEINLINE AEVector4f &AEMatrix4f::GetColumn( AEINT32 nIdx )
{
	AEASSERT( nIdx <= 3 );
	return (&m_vcColumn0)[nIdx];
}

AE_FORCEINLINE const AEVector4f &AEMatrix4f::GetColumn( AEINT32 nIdx ) const
{
	AEASSERT( nIdx <= 3 );
	return (&m_vcColumn0)[nIdx];
}

template <AEINT32 N>
AE_FORCEINLINE const AEVector4f &AEMatrix4f::GetColumn( void ) const
{
	return (&m_vcColumn0)[N];
}

template <AEINT32 N>
AE_FORCEINLINE AEVector4f &AEMatrix4f::GetColumn( void )
{
	return (&m_vcColumn0)[N];
}

template <AEINT32 N> 
AE_FORCEINLINE void AEMatrix4f::SetColumn( AEVector4fRefParam vcValues )
{
	AEASSERT( N <= 3 );
	(&m_vcColumn0)[N] = vcValues;
}

AE_FORCEINLINE void AEMatrix4f::GetRow( AEINT32 nRow, AEVector4f &vcOut ) const
{
	vcOut.Set( m_vcColumn0( nRow ), m_vcColumn1( nRow ), m_vcColumn2( nRow ), m_vcColumn3( nRow ) );
}

template <AEINT32 I>
AE_FORCEINLINE void AEMatrix4f::GetRow( AEVector4f &vcOut ) const
{
	vcOut.Set( GetElement<I,0>(), GetElement<I,1>(), GetElement<I,2>(), GetElement<I,3>() );
}

AE_FORCEINLINE void AEMatrix4f::SetRow( AEINT32 nRow, AEVector4fRefParam vcRow )
{
	m_vcColumn0( nRow ) = vcRow(0);
	m_vcColumn1( nRow ) = vcRow(1);
	m_vcColumn2( nRow ) = vcRow(2);
	m_vcColumn3( nRow ) = vcRow(3);
}

template <int I>
AE_FORCEINLINE void AEMatrix4f::SetRow( AEVector4fRefParam vcRow )
{
	SetElement<I,0>( vcRow.GetComponent<0>() );
	SetElement<I,1>( vcRow.GetComponent<1>() );
	SetElement<I,2>( vcRow.GetComponent<2>() );
	SetElement<I,3>( vcRow.GetComponent<3>() );
}

AE_FORCEINLINE AEFLOAT32 &AEMatrix4f::operator() ( AEINT32 nRow, AEINT32 nCol )
{
	return GetColumn(nCol)(nRow);
}

AE_FORCEINLINE const AEFLOAT32 &AEMatrix4f::operator() ( AEINT32 nRow, AEINT32 nCol ) const
{
	return GetColumn(nCol)(nRow);
}

template <AEINT32 ROW, AEINT32 COL>	
AE_FORCEINLINE const AESimdFloat32 AEMatrix4f::GetElement( void ) const
{
	return (&m_vcColumn0)[COL].GetComponent<ROW>();
}

template <AEINT32 ROW, AEINT32 COL> 
AE_FORCEINLINE void AEMatrix4f::SetElement( AESimdFloat32ConstRef fValue )
{
	(&m_vcColumn0)[COL].SetComponent<ROW>( fValue );
}

AE_FORCEINLINE void AEMatrix4f::SetRows( AEVector4fRefParam vcRow0, AEVector4fRefParam vcRow1, AEVector4fRefParam vcRow2, AEVector4fRefParam vcRow3 )
{
#if (AE_CONFIG_SIMD == AE_CONFIG_SIMD_ENABLED)
	m_vcColumn0 = vcRow0;
	m_vcColumn1 = vcRow1;
	m_vcColumn2 = vcRow2;
	m_vcColumn3 = vcRow3;

	AE_VECTORTRANSPOSE4F( m_vcColumn0, m_vcColumn1, m_vcColumn2, m_vcColumn3 );
#else
	AEVector4f c0,c1,c2,c3;

	c0.Set( vcRow0(0), vcRow1(0), vcRow2(0), vcRow3(0) );
	c1.Set( vcRow0(1), vcRow1(1), vcRow2(1), vcRow3(1) );
	c2.Set( vcRow0(2), vcRow1(2), vcRow2(2), vcRow3(2) );
	c3.Set( vcRow0(3), vcRow1(3), vcRow2(3), vcRow3(3) );
	
	SetColumn<0>(c0);
	SetColumn<1>(c1);
	SetColumn<2>(c2);
	SetColumn<3>(c3);
#endif
}

AE_FORCEINLINE void AEMatrix4f::GetRows( AEVector4f &vcRow0, AEVector4f &vcRow1, AEVector4f &vcRow2, AEVector4f &vcRow3 ) const
{
#if (AE_CONFIG_SIMD == AE_CONFIG_SIMD_ENABLED)
	AEVector4f c0 = GetColumn<0>();
	AEVector4f c1 = GetColumn<1>();
	AEVector4f c2 = GetColumn<2>();
	AEVector4f c3 = GetColumn<3>();
	
	AE_VECTORTRANSPOSE4F( c0, c1, c2, c3 );
#else
	AEVector4f c0, c1, c2, c3;

	c0.Set( m_vcColumn0(0), m_vcColumn1(0), m_vcColumn2(0), m_vcColumn3(0) );
	c1.Set( m_vcColumn0(1), m_vcColumn1(1), m_vcColumn2(1), m_vcColumn3(1) );
	c2.Set( m_vcColumn0(2), m_vcColumn1(2), m_vcColumn2(2), m_vcColumn3(2) );
	c3.Set( m_vcColumn0(3), m_vcColumn1(3), m_vcColumn2(3), m_vcColumn3(3) );
#endif

	vcRow0 = c0;
	vcRow1 = c1;
	vcRow2 = c2;
	vcRow3 = c3;
}

AE_FORCEINLINE void AEMatrix4f::SetCols( AEVector4fRefParam vcCol0, AEVector4fRefParam vcCol1, AEVector4fRefParam vcCol2, AEVector4fRefParam vcCol3 )
{
	m_vcColumn0 = vcCol0;
	m_vcColumn1 = vcCol1;
	m_vcColumn2 = vcCol2;
	m_vcColumn3 = vcCol3;
}

AE_FORCEINLINE void AEMatrix4f::GetCols( AEVector4f &vcCol0, AEVector4f &vcCol1, AEVector4f &vcCol2, AEVector4f &vcCol3 ) const
{
	vcCol0 = m_vcColumn0;
	vcCol1 = m_vcColumn1;
	vcCol2 = m_vcColumn2;
	vcCol3 = m_vcColumn3;
}

AE_FORCEINLINE void AEMatrix4f::SetZero( void )
{
	m_vcColumn0.SetZero();
	m_vcColumn1.SetZero();
	m_vcColumn2.SetZero();
	m_vcColumn3.SetZero();
}

AE_FORCEINLINE void AEMatrix4f::SetDiagonal( AEFLOAT32 fM00, AEFLOAT32 fM11, AEFLOAT32 fM22, AEFLOAT32 fM33 )
{
	SetZero();
	m_vcColumn0(0) = fM00;
	m_vcColumn1(1) = fM11;
	m_vcColumn2(2) = fM22;
	m_vcColumn3(3) = fM33;
}

AE_FORCEINLINE void AEMatrix4f::SetDiagonal( AESimdFloat32ConstRef fM00, AESimdFloat32ConstRef fM11, AESimdFloat32ConstRef fM22, AESimdFloat32ConstRef fM33 )
{
#if (AE_CONFIG_SIMD == AE_CONFIG_SIMD_ENABLED)
	const AEVector4f *id = (const AEVector4f*)(g_vectorfConstants + AE_QUADREAL_1000);
	m_vcColumn0.SetMul( id[0], fM00 );
	m_vcColumn1.SetMul( id[1], fM11 );
	m_vcColumn2.SetMul( id[2], fM22 );
	m_vcColumn3.SetMul( id[3], fM33 );
#else
	SetZero();
	m_vcColumn0(0) = fM00.GetReal();
	m_vcColumn1(1) = fM11.GetReal();
	m_vcColumn2(2) = fM22.GetReal();
	m_vcColumn3(3) = fM33.GetReal();
#endif
}

AE_FORCEINLINE void AEMatrix4f::SetDiagonal( AEVector4fRefParam vcDiagonal )
{
#if (AE_CONFIG_SIMD == AE_CONFIG_SIMD_ENABLED)
	const AEVector4f *id = (const AEVector4f*)(g_vectorfConstants + AE_QUADREAL_1000);
	m_vcColumn0.SetMul( id[0], vcDiagonal );
	m_vcColumn1.SetMul( id[1], vcDiagonal );
	m_vcColumn2.SetMul( id[2], vcDiagonal );
	m_vcColumn3.SetMul( id[3], vcDiagonal );
#else
	SetZero();
	m_vcColumn0(0) = vcDiagonal(0);
	m_vcColumn1(1) = vcDiagonal(1);
	m_vcColumn2(2) = vcDiagonal(2);
	m_vcColumn3(3) = vcDiagonal(3);
#endif
}

AE_FORCEINLINE void AEMatrix4f::GetDiagonal( AEVector4f &vcDiagonalOut ) const
{
#if (AE_CONFIG_SIMD == AE_CONFIG_SIMD_ENABLED)
	const AEVector4f *id = (const AEVector4f*)(g_vectorfConstants + AE_QUADREAL_1000);
	vcDiagonalOut.SetZero();
	vcDiagonalOut.AddMul( id[0], m_vcColumn0 );
	vcDiagonalOut.AddMul( id[1], m_vcColumn1 );
	vcDiagonalOut.AddMul( id[2], m_vcColumn2 );
	vcDiagonalOut.AddMul( id[3], m_vcColumn3 );
#else
	vcDiagonalOut.Set( m_vcColumn0(0), m_vcColumn1(1), m_vcColumn2(2), m_vcColumn3(3) );
#endif
}

AE_FORCEINLINE void AEMatrix4f::SetIdentity( void )
{
	m_vcColumn0 = AEVector4f::GetConstant<AE_QUADREAL_1000>();
	m_vcColumn1 = AEVector4f::GetConstant<AE_QUADREAL_0100>();
	m_vcColumn2 = AEVector4f::GetConstant<AE_QUADREAL_0010>();
	m_vcColumn3 = AEVector4f::GetConstant<AE_QUADREAL_0001>();
}

AE_FORCEINLINE void AEMatrix4f::Get( AEFLOAT32 *lpCopyTo, AEMatrixLayout aemlLayout ) const
{
	AEASSERT( lpCopyTo != NULL );
	
	if( aemlLayout == AEML_ColumnMajor )
	{
		lpCopyTo[0] = m_vcColumn0.GetComponent<0>();
		lpCopyTo[1] = m_vcColumn0.GetComponent<1>();
		lpCopyTo[2] = m_vcColumn0.GetComponent<2>();
		lpCopyTo[3] = m_vcColumn0.GetComponent<3>();

		lpCopyTo[4] = m_vcColumn1.GetComponent<0>();
		lpCopyTo[5] = m_vcColumn1.GetComponent<1>();
		lpCopyTo[6] = m_vcColumn1.GetComponent<2>();
		lpCopyTo[7] = m_vcColumn1.GetComponent<3>();

		lpCopyTo[8] = m_vcColumn2.GetComponent<0>();
		lpCopyTo[9] = m_vcColumn2.GetComponent<1>();
		lpCopyTo[10] = m_vcColumn2.GetComponent<2>();
		lpCopyTo[11] = m_vcColumn2.GetComponent<3>();

		lpCopyTo[12] = m_vcColumn3.GetComponent<0>();
		lpCopyTo[13] = m_vcColumn3.GetComponent<1>();
		lpCopyTo[14] = m_vcColumn3.GetComponent<2>();
		lpCopyTo[15] = m_vcColumn3.GetComponent<3>();
	}
	else
	{
		lpCopyTo[0] = m_vcColumn0.GetComponent<0>();
		lpCopyTo[1] = m_vcColumn1.GetComponent<0>();
		lpCopyTo[2] = m_vcColumn2.GetComponent<0>();
		lpCopyTo[3] = m_vcColumn3.GetComponent<0>();
		
		lpCopyTo[4] = m_vcColumn0.GetComponent<1>();
		lpCopyTo[5] = m_vcColumn1.GetComponent<1>();
		lpCopyTo[6] = m_vcColumn2.GetComponent<1>();
		lpCopyTo[7] = m_vcColumn3.GetComponent<1>();
		
		lpCopyTo[8] = m_vcColumn0.GetComponent<2>();
		lpCopyTo[9] = m_vcColumn1.GetComponent<2>();
		lpCopyTo[10] = m_vcColumn2.GetComponent<2>();
		lpCopyTo[11] = m_vcColumn3.GetComponent<2>();
		
		lpCopyTo[12] = m_vcColumn0.GetComponent<3>();
		lpCopyTo[13] = m_vcColumn1.GetComponent<3>();
		lpCopyTo[14] = m_vcColumn2.GetComponent<3>();
		lpCopyTo[15] = m_vcColumn3.GetComponent<3>();
	}
}

AE_FORCEINLINE void AEMatrix4f::Set( const AEFLOAT32 *lpCopyFrom, AEMatrixLayout aemlLayout )
{
	AEASSERT( lpCopyFrom != NULL );
	
	if( aemlLayout == AEML_ColumnMajor)
	{
		m_vcColumn0.Set( lpCopyFrom[0], lpCopyFrom[1], lpCopyFrom[2], lpCopyFrom[3] );
		m_vcColumn1.Set( lpCopyFrom[4], lpCopyFrom[5], lpCopyFrom[6], lpCopyFrom[7] );
		m_vcColumn2.Set( lpCopyFrom[8], lpCopyFrom[9], lpCopyFrom[10], lpCopyFrom[11] );
		m_vcColumn3.Set( lpCopyFrom[12], lpCopyFrom[13], lpCopyFrom[14], lpCopyFrom[15] );
	}
	else
	{
		m_vcColumn0.Set( lpCopyFrom[0], lpCopyFrom[4], lpCopyFrom[8], lpCopyFrom[12] );
		m_vcColumn1.Set( lpCopyFrom[1], lpCopyFrom[5], lpCopyFrom[9], lpCopyFrom[13] );
		m_vcColumn2.Set( lpCopyFrom[2], lpCopyFrom[6], lpCopyFrom[10], lpCopyFrom[14] );
		m_vcColumn3.Set( lpCopyFrom[3], lpCopyFrom[7], lpCopyFrom[11], lpCopyFrom[15] );		
	}
}

AE_FORCEINLINE void AEMatrix4f::SetTranspose( const AEMatrix4f &mtSource )
{
	SetRows( mtSource.GetColumn<0>(), mtSource.GetColumn<1>(), mtSource.GetColumn<2>(), mtSource.GetColumn<3>());
}

AE_FORCEINLINE void AEMatrix4f::SetMul( const AEMatrix4f &mMatrix1, const AEMatrix4f &mMatrix2 )
{
	AEASSERT( this != &mMatrix1 );
	AEASSERT( this != &mMatrix2 );
	
#if (AE_CONFIG_SIMD == AE_CONFIG_SIMD_ENABLED)
	AEVector4f col0, col1, col2, col3;
	AEVector4f row0, row1, row2, row3;
	/*mMatrix2.GetRow<0>( row0 );
	mMatrix2.GetRow<1>( row1 );
	mMatrix2.GetRow<2>( row2 );
	mMatrix2.GetRow<3>( row3 );

	col0.Set( mMatrix1.m_vcColumn0.GetDot<4>( row0 ),
		mMatrix1.m_vcColumn1.GetDot<4>( row0 ),
		mMatrix1.m_vcColumn2.GetDot<4>( row0 ),
		mMatrix1.m_vcColumn3.GetDot<4>( row0 )
	 );

	col1.Set( mMatrix1.m_vcColumn0.GetDot<4>( row1 ),
		mMatrix1.m_vcColumn1.GetDot<4>( row1 ),
		mMatrix1.m_vcColumn2.GetDot<4>( row1 ),
		mMatrix1.m_vcColumn3.GetDot<4>( row1 )
	 );

	col2.Set( mMatrix1.m_vcColumn0.GetDot<4>( row2 ),
		mMatrix1.m_vcColumn1.GetDot<4>( row2 ),
		mMatrix1.m_vcColumn2.GetDot<4>( row2 ),
		mMatrix1.m_vcColumn3.GetDot<4>( row2 )
	 );

	col3.Set( mMatrix1.m_vcColumn0.GetDot<4>( row3 ),
		mMatrix1.m_vcColumn1.GetDot<4>( row3 ),
		mMatrix1.m_vcColumn2.GetDot<4>( row3 ),
		mMatrix1.m_vcColumn3.GetDot<4>( row3 )
	 );*/

	 
	col0.SetMul( mMatrix2.m_vcColumn0.GetComponent<0>(), mMatrix1.m_vcColumn0 );
	col1.SetMul( mMatrix2.m_vcColumn1.GetComponent<0>(), mMatrix1.m_vcColumn0 );
	col2.SetMul( mMatrix2.m_vcColumn2.GetComponent<0>(), mMatrix1.m_vcColumn0 );
	col3.SetMul( mMatrix2.m_vcColumn3.GetComponent<0>(), mMatrix1.m_vcColumn0 );

	col0.AddMul( mMatrix2.m_vcColumn0.GetComponent<1>(), mMatrix1.m_vcColumn1 );
	col1.AddMul( mMatrix2.m_vcColumn1.GetComponent<1>(), mMatrix1.m_vcColumn1 );
	col2.AddMul( mMatrix2.m_vcColumn2.GetComponent<1>(), mMatrix1.m_vcColumn1 );
	col3.AddMul( mMatrix2.m_vcColumn3.GetComponent<1>(), mMatrix1.m_vcColumn1 );

	col0.AddMul( mMatrix2.m_vcColumn0.GetComponent<2>(), mMatrix1.m_vcColumn2 );
	col1.AddMul( mMatrix2.m_vcColumn1.GetComponent<2>(), mMatrix1.m_vcColumn2 );
	col2.AddMul( mMatrix2.m_vcColumn2.GetComponent<2>(), mMatrix1.m_vcColumn2 );
	col3.AddMul( mMatrix2.m_vcColumn3.GetComponent<2>(), mMatrix1.m_vcColumn2 );

	col0.AddMul( mMatrix2.m_vcColumn0.GetComponent<3>(), mMatrix1.m_vcColumn3 );
	col1.AddMul( mMatrix2.m_vcColumn1.GetComponent<3>(), mMatrix1.m_vcColumn3 );
	col2.AddMul( mMatrix2.m_vcColumn2.GetComponent<3>(), mMatrix1.m_vcColumn3 );
	col3.AddMul( mMatrix2.m_vcColumn3.GetComponent<3>(), mMatrix1.m_vcColumn3 );
	
	m_vcColumn0 = col0;
	m_vcColumn1 = col1;
	m_vcColumn2 = col2;
	m_vcColumn3 = col3;
	/*
	AEMatrix4f& result = *this;

	for (int c=0; c < 4; c++)
	{
		for (int r=0; r < 4; r++)
		{
			result(r,c) = mMatrix1.GetColumn(r).GetDot<4>( mMatrix2.GetColumn(c) ).GetReal();
		}
	}*/
#else
	AEMatrix4f aTrans = mMatrix1;
	aTrans.Transpose();

	AEMatrix4f& result = *this;

	for (int c=0; c < 4; c++)
	{
		for (int r=0; r < 4; r++)
		{
			result(r,c) = aTrans.GetColumn(r).GetDot<4>( mMatrix2.GetColumn(c) ).GetReal();
		}
	}
#endif
}

AE_FORCEINLINE void AEMatrix4f::SetMul( AESimdFloat32ConstRef fScale, const AEMatrix4f &mtMatrix )
{
	m_vcColumn0.SetMul( fScale, mtMatrix.GetColumn<0>() );
	m_vcColumn1.SetMul( fScale, mtMatrix.GetColumn<1>() );
	m_vcColumn2.SetMul( fScale, mtMatrix.GetColumn<2>() );
	m_vcColumn3.SetMul( fScale, mtMatrix.GetColumn<3>() );
}

AE_FORCEINLINE void AEMatrix4f::Add( const AEMatrix4f &mtMatrix )
{
	m_vcColumn0.Add( mtMatrix.GetColumn<0>() );
	m_vcColumn1.Add( mtMatrix.GetColumn<1>() );
	m_vcColumn2.Add( mtMatrix.GetColumn<2>() );
	m_vcColumn3.Add( mtMatrix.GetColumn<3>() );
}

AE_FORCEINLINE void AEMatrix4f::Sub( const AEMatrix4f &mtMatrix )
{
	m_vcColumn0.Sub( mtMatrix.GetColumn<0>() );
	m_vcColumn1.Sub( mtMatrix.GetColumn<1>() );
	m_vcColumn2.Sub( mtMatrix.GetColumn<2>() );
	m_vcColumn3.Sub( mtMatrix.GetColumn<3>() );
}

AE_FORCEINLINE void AEMatrix4f::Mul( AESimdFloat32ConstRef fScale )
{
	m_vcColumn0.Mul( fScale );
	m_vcColumn1.Mul( fScale );
	m_vcColumn2.Mul( fScale );
	m_vcColumn3.Mul( fScale );
}

AE_FORCEINLINE void AEMatrix4f::Mul( const AEMatrix4f &matRhs )
{
	AEMatrix4f temp;
	temp.SetMul( *this, matRhs );
	*this = temp;
}

AE_FORCEINLINE void AEMatrix4f::MultiplyVector( AEVector4fRefParam vcVectorIn, AEVector4f &vcResultOut ) const
{
	/*
		    [M11 M12 M13 M14]   [V.x]   [M11 * V.x + M12 * V.y + M13 * V.z + M14 * V.h]
	M * V = [M21 M22 M23 M24] * [V.y] = [M21 * V.x + M22 * V.y + M23 * V.z + M24 * V.h]
			[M31 M32 M33 M34]   [V.z]   [M31 * V.x + M32 * V.y + M33 * V.z + M34 * V.h]
			[M41 M42 M43 M44]   [V.h]   [M41 * V.x + M42 * V.y + M43 * V.z + M44 * V.h]
	*/
	const AESimdFloat32 fVx = vcVectorIn.GetComponent<0>();
	const AESimdFloat32 fVy = vcVectorIn.GetComponent<1>();
	const AESimdFloat32 fVz = vcVectorIn.GetComponent<2>();
	const AESimdFloat32 fVw = vcVectorIn.GetComponent<3>();
	
	AEVector4f t0;
	t0.SetMul( fVx, m_vcColumn0 );
	t0.AddMul( fVy, m_vcColumn1 );
	t0.AddMul( fVz, m_vcColumn2 );
	t0.AddMul( fVw, m_vcColumn3 );
	
	vcResultOut = t0;
}

AE_FORCEINLINE void AEMatrix4f::operator= ( const AEMatrix4f &mtSource )
{
	m_vcColumn0 = mtSource.GetColumn<0>();
	m_vcColumn1 = mtSource.GetColumn<1>();
	m_vcColumn2 = mtSource.GetColumn<2>();
	m_vcColumn3 = mtSource.GetColumn<3>();
}

AE_FORCEINLINE void AEMatrix4f::Set( float c0r0, float c1r0, float c2r0, float c3r0,
                          float c0r1, float c1r1, float c2r1, float c3r1,
                          float c0r2, float c1r2, float c2r2, float c3r2,
                          float c0r3, float c1r3, float c2r3, float c3r3,
                          AEMatrixLayout aemlLayout )
{
	if( aemlLayout == AEML_RowMajor )
	{
		m_vcColumn0.Set( c0r0, c1r0, c2r0, c3r0 );
		m_vcColumn1.Set( c0r1, c1r1, c2r1, c3r1 );
		m_vcColumn2.Set( c0r2, c1r2, c2r2, c3r2 );
		m_vcColumn3.Set( c0r3, c1r3, c2r3, c3r3 );
	}
	else
	{
		m_vcColumn0.Set( c0r0, c0r1, c0r2, c0r3 );
		m_vcColumn1.Set( c1r0, c1r1, c1r2, c1r3 );
		m_vcColumn2.Set( c2r0, c2r1, c2r2, c2r3 );
		m_vcColumn3.Set( c3r0, c3r1, c3r2, c3r3 );
	}
}

AE_FORCEINLINE const AEVector4f AEMatrix4f::TransformPosition( const AEVector4f &vcVector ) const
{
// TODO
/*	HKVVEC3_COPYTEMPS (v);

	const AEFLOAT32 rx = m_Column[0][0] * v_x + m_Column[1][0] * v_y + m_Column[2][0] * v_z + m_Column[3][0];
	const AEFLOAT32 ry = m_Column[0][1] * v_x + m_Column[1][1] * v_y + m_Column[2][1] * v_z + m_Column[3][1];
	const AEFLOAT32 rz = m_Column[0][2] * v_x + m_Column[1][2] * v_y + m_Column[2][2] * v_z + m_Column[3][2];
	return AEVector4f( rx, ry, rz, 1.f );
*/
	return AEVector4f( 1.f, 1.f, 1.f, 1.f );
}

#endif
// _AEMATRIX4F_INL_
